package com.cmc.cloud.cmclink.doc.rpcservice.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.cmc.cloud.cmclink.doc.api.document.emums.SendEdoPortEnum;
import com.cmc.cloud.cmclink.doc.entity.BlnoSendEdoLogDO;
import com.cmc.cloud.cmclink.doc.mapper.BlnoSendEdoLogMapper;
import com.cmc.cloud.cmclink.doc.rpcservice.EdiTransferService;
import com.cmc.cloud.cmclink.doc.rpcservice.constants.RpcErrorCodeConstants;
import com.cmc.cloud.cmclink.doc.service.BlnoSendEdoLogService;
import com.cmc.cloud.cmclink.doc.vo.blnovo.BlnoBaseInfoVO;
import com.cmc.cloud.cmclink.doc.vo.edo.CnDlcEdoBaseVO;
import com.cmc.cloud.cmclink.doc.vo.edo.CnTaoEdoBaseVO;
import com.cmc.cloud.cmclink.doc.vo.edo.CnTxgEdoBaseVO;
import com.cmc.cloud.cmclink.doc.vo.edo.EdoBaseVO;
import com.cmc.cloud.cmclink.edi.bizapi.api.edo.PortEdoApi;
import com.cmc.cloud.cmclink.edi.bizapi.api.edo.base.EdoBaseResult;
import com.cmc.cloud.cmclink.edi.bizapi.api.edo.base.SIBaseRequestDTO;
import com.cmc.cloud.cmclink.edi.bizapi.api.edo.cndlc.req.CndlcEdoRequestDTO;
import com.cmc.cloud.cmclink.edi.bizapi.api.edo.cntao.req.CntaoEdoRequestDTO;
import com.cmc.cloud.cmclink.edi.bizapi.api.edo.cntxg.req.CntxgEdoRequestDTO;
import com.cmes.framework.common.exception.util.ServiceExceptionUtil;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;


import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * Edi交互service
 *
 * @author heguo
 * @date 20251013
 **/
@Service
@Slf4j
public class EdiTransferServiceImpl implements EdiTransferService {

    @Resource
    private PortEdoApi portEdoApi;

    private static String EDI_SUCCESS = "0";

    @Resource
    private BlnoSendEdoLogService blnoSendEdoLogService;

    /**
     * 发送EDO
     *
     * @param edoBaseVos 发送edo参数
     * @param sendEdoPort 发送edo港口
     * @return result edo响应
     */
    @Override
    public EdoBaseResult sendEdo(List<EdoBaseVO> edoBaseVos,String sendEdoPort,String doOpType) {

        if (SendEdoPortEnum.CNTAO.getCode().equals(sendEdoPort) || SendEdoPortEnum.CNRZH.getCode().equals(sendEdoPort)){
            this.sendCnTaoEdo(edoBaseVos,sendEdoPort,doOpType);
        }else if (SendEdoPortEnum.CNDLC.getCode().equals(sendEdoPort)){
            this.sendCnDlcEdo(edoBaseVos,sendEdoPort,doOpType);
        } else if (SendEdoPortEnum.CNTXG.getCode().equals(sendEdoPort)){
            this.sendCnTxgEdo(edoBaseVos,sendEdoPort,doOpType);
        }
        return null;
    }

    private EdoBaseResult sendCnTaoEdo(List<EdoBaseVO> edoBaseVos,String sendEdoPort,String doOpType) {
        CntaoEdoRequestDTO cntaoEdoRequestDto = new CntaoEdoRequestDTO();
        List<CntaoEdoRequestDTO.CntaoEdoRequestItem> data = new ArrayList<>();
        cntaoEdoRequestDto.setData(data);
        edoBaseVos.stream().forEach(edoBaseVo -> {
            CnTaoEdoBaseVO cnTaoEdoBaseVo = (CnTaoEdoBaseVO) edoBaseVo;
            CntaoEdoRequestDTO.CntaoEdoRequestItem cntaoEdoRequestItem = BeanUtil.copyProperties(cnTaoEdoBaseVo.getBlnoInfoVo().getBlnoBasInfoVO(),CntaoEdoRequestDTO.CntaoEdoRequestItem.class);
            data.add(cntaoEdoRequestItem);
            cntaoEdoRequestItem.setMsgType(cnTaoEdoBaseVo.getMsgType());
            cntaoEdoRequestItem.setVslvoyList(BeanUtil.copyToList(cnTaoEdoBaseVo.getBlnoInfoVo().getBlnoVslvoys(), SIBaseRequestDTO.VslvoyInfo.class));
            cntaoEdoRequestItem.setCargoList(BeanUtil.copyToList(cnTaoEdoBaseVo.getBlnoInfoVo().getBlnoCargos(), SIBaseRequestDTO.CargoInfo.class));
            cntaoEdoRequestItem.setScnList(BeanUtil.copyToList(cnTaoEdoBaseVo.getBlnoInfoVo().getBlnoScns(), SIBaseRequestDTO.ScnInfo.class));
            cntaoEdoRequestItem.setCntrList(BeanUtil.copyToList(cnTaoEdoBaseVo.getBlnoInfoVo().getBlnoCntrs(), SIBaseRequestDTO.CntrInfo.class));
            cntaoEdoRequestItem.setPaymentList(BeanUtil.copyToList(cnTaoEdoBaseVo.getBlnoInfoVo().getBlnoPayments(), SIBaseRequestDTO.PaymentInfo.class));
            cntaoEdoRequestItem.setVgmList(BeanUtil.copyToList(cnTaoEdoBaseVo.getBlnoInfoVo().getVgmCreateReqVos(), SIBaseRequestDTO.VgmInfo.class));
            cntaoEdoRequestItem.setEdoBatchNo(edoBaseVo.getEdoBatchNo());

            CntaoEdoRequestDTO.CntaoEdoRequestItem.CntaoEdoInfo cntaoEdoInfo = BeanUtil.copyProperties(cnTaoEdoBaseVo,CntaoEdoRequestDTO.CntaoEdoRequestItem.CntaoEdoInfo.class);
            cntaoEdoRequestItem.setEdo(cntaoEdoInfo);
        });
        String jsonString = JSONObject.toJSONString(cntaoEdoRequestDto);
        log.info("cntaoEdoRequestDto= {}",jsonString);
        EdoBaseResult edoBaseResult = portEdoApi.submitQingdaoEdo(cntaoEdoRequestDto);
        this.cnTaoSendLog(edoBaseVos,cntaoEdoRequestDto,edoBaseResult,sendEdoPort,doOpType);
        if (!ObjectUtils.isEmpty(edoBaseResult) && EDI_SUCCESS.equals(edoBaseResult.getCode())){
            return edoBaseResult;
        }else {
            throw ServiceExceptionUtil.exception(RpcErrorCodeConstants.SEND_EDO_ERROR);
        }
    }
    private EdoBaseResult sendCnDlcEdo(List<EdoBaseVO> edoBaseVos,String sendEdoPort,String doOpType) {
        CndlcEdoRequestDTO cndlcEdoRequestDto = new CndlcEdoRequestDTO();
        List<CndlcEdoRequestDTO.CndlcEdoRequestItem> data = new ArrayList<>();
        edoBaseVos.stream().forEach(edoBaseVo -> {
            CnDlcEdoBaseVO cnDlcEdoBaseVo = (CnDlcEdoBaseVO) edoBaseVo;
            CndlcEdoRequestDTO.CndlcEdoRequestItem cndlcEdoRequestItem = BeanUtil.copyProperties(cnDlcEdoBaseVo.getBlnoInfoVo().getBlnoBasInfoVO(),CndlcEdoRequestDTO.CndlcEdoRequestItem.class);
            data.add(cndlcEdoRequestItem);
            cndlcEdoRequestItem.setVslvoyList(BeanUtil.copyToList(cnDlcEdoBaseVo.getBlnoInfoVo().getBlnoVslvoys(), SIBaseRequestDTO.VslvoyInfo.class));
            cndlcEdoRequestItem.setCargoList(BeanUtil.copyToList(cnDlcEdoBaseVo.getBlnoInfoVo().getBlnoCargos(), SIBaseRequestDTO.CargoInfo.class));
            cndlcEdoRequestItem.setScnList(BeanUtil.copyToList(cnDlcEdoBaseVo.getBlnoInfoVo().getBlnoScns(), SIBaseRequestDTO.ScnInfo.class));
            cndlcEdoRequestItem.setCntrList(BeanUtil.copyToList(cnDlcEdoBaseVo.getBlnoInfoVo().getBlnoCntrs(), SIBaseRequestDTO.CntrInfo.class));
            cndlcEdoRequestItem.setFreightList(BeanUtil.copyToList(cnDlcEdoBaseVo.getBlnoInfoVo().getBlnoFreights(), SIBaseRequestDTO.FreightInfo.class));
            cndlcEdoRequestItem.setPaymentList(BeanUtil.copyToList(cnDlcEdoBaseVo.getBlnoInfoVo().getBlnoPayments(), SIBaseRequestDTO.PaymentInfo.class));
            cndlcEdoRequestItem.setVgmList(BeanUtil.copyToList(cnDlcEdoBaseVo.getBlnoInfoVo().getVgmCreateReqVos(), SIBaseRequestDTO.VgmInfo.class));
            cndlcEdoRequestItem.setEdoBatchNo(edoBaseVo.getEdoBatchNo());
            CndlcEdoRequestDTO.CndlcEdoRequestItem.CndlcEdoInfo cndlcEdoInfo = BeanUtil.copyProperties(cnDlcEdoBaseVo, CndlcEdoRequestDTO.CndlcEdoRequestItem.CndlcEdoInfo.class);

            cndlcEdoRequestItem.setEdo(cndlcEdoInfo);
        });
        cndlcEdoRequestDto.setData(data);
        String jsonString = JSONObject.toJSONString(cndlcEdoRequestDto);
        log.info("cndlcEdoRequestDto= {}",jsonString);
        EdoBaseResult edoBaseResult = portEdoApi.submitDalianEdo(cndlcEdoRequestDto);
        this.cnDlcSendLog(edoBaseVos,cndlcEdoRequestDto,edoBaseResult,sendEdoPort,doOpType);
        if (!ObjectUtils.isEmpty(edoBaseResult) && EDI_SUCCESS.equals(edoBaseResult.getCode())){
            return edoBaseResult;
        }else {
            log.error("edi response :{}",edoBaseResult);
            throw ServiceExceptionUtil.exception(RpcErrorCodeConstants.SEND_EDO_ERROR);
        }
    }
    private EdoBaseResult sendCnTxgEdo(List<EdoBaseVO> edoBaseVos,String sendEdoPort,String doOpType) {
        CntxgEdoRequestDTO cntxgEdoRequestDto = new CntxgEdoRequestDTO();
        List<CntxgEdoRequestDTO.CntxgEdoRequestItem> data = new ArrayList<>();
        edoBaseVos.stream().forEach(edoBaseVo -> {
            CnTxgEdoBaseVO cnTxgEdoBaseVo = (CnTxgEdoBaseVO) edoBaseVo;
            CntxgEdoRequestDTO.CntxgEdoRequestItem cntxgEdoRequestItem = BeanUtil.copyProperties(cnTxgEdoBaseVo.getBlnoInfoVo().getBlnoBasInfoVO(),CntxgEdoRequestDTO.CntxgEdoRequestItem.class);
            data.add(cntxgEdoRequestItem);
            cntxgEdoRequestItem.setVslvoyList(BeanUtil.copyToList(cnTxgEdoBaseVo.getBlnoInfoVo().getBlnoVslvoys(), SIBaseRequestDTO.VslvoyInfo.class));
            cntxgEdoRequestItem.setCargoList(BeanUtil.copyToList(cnTxgEdoBaseVo.getBlnoInfoVo().getBlnoCargos(), SIBaseRequestDTO.CargoInfo.class));
            cntxgEdoRequestItem.setScnList(BeanUtil.copyToList(cnTxgEdoBaseVo.getBlnoInfoVo().getBlnoScns(), SIBaseRequestDTO.ScnInfo.class));
            cntxgEdoRequestItem.setCntrList(BeanUtil.copyToList(cnTxgEdoBaseVo.getBlnoInfoVo().getBlnoCntrs(), SIBaseRequestDTO.CntrInfo.class));
            cntxgEdoRequestItem.setFreightList(BeanUtil.copyToList(cnTxgEdoBaseVo.getBlnoInfoVo().getBlnoFreights(), SIBaseRequestDTO.FreightInfo.class));
            cntxgEdoRequestItem.setPaymentList(BeanUtil.copyToList(cnTxgEdoBaseVo.getBlnoInfoVo().getBlnoPayments(), SIBaseRequestDTO.PaymentInfo.class));
            cntxgEdoRequestItem.setVgmList(BeanUtil.copyToList(cnTxgEdoBaseVo.getBlnoInfoVo().getVgmCreateReqVos(), SIBaseRequestDTO.VgmInfo.class));
            cntxgEdoRequestItem.setEdoBatchNo(edoBaseVo.getEdoBatchNo());
            CntxgEdoRequestDTO.CntxgEdoRequestItem.CntxgEdoInfo cntxgEdoInfo = BeanUtil.copyProperties(cnTxgEdoBaseVo, CntxgEdoRequestDTO.CntxgEdoRequestItem.CntxgEdoInfo.class);
            cntxgEdoRequestItem.setEdo(cntxgEdoInfo);
        });
        cntxgEdoRequestDto.setData(data);
        String jsonString = JSONObject.toJSONString(cntxgEdoRequestDto);
        log.info("cntxgEdoRequestDto= {}",jsonString);
        EdoBaseResult edoBaseResult = portEdoApi.submitTianjinEdo(cntxgEdoRequestDto);
        this.cnTxgSendLog(edoBaseVos,cntxgEdoRequestDto,edoBaseResult,sendEdoPort,doOpType);
        if (!ObjectUtils.isEmpty(edoBaseResult) && EDI_SUCCESS.equals(edoBaseResult.getCode())){
            return edoBaseResult;
        }else {
            throw ServiceExceptionUtil.exception(RpcErrorCodeConstants.SEND_EDO_ERROR);
        }
    }

    private void cnTaoSendLog(@NotNull List<EdoBaseVO> edoBaseVos, @NotNull CntaoEdoRequestDTO cntaoEdoRequestDto, EdoBaseResult edoBaseResult,String sendEdoPort, String doOpType ){
        if (!ObjectUtils.isEmpty(edoBaseVos.get(0)) && !ObjectUtils.isEmpty(edoBaseVos.get(0).getBlnoInfoVo().getBlnoBasInfoVO())){
            BlnoBaseInfoVO blnoBasInfoVo = edoBaseVos.get(0).getBlnoInfoVo().getBlnoBasInfoVO();
            BlnoSendEdoLogDO blnoSendEdoLogDo = new BlnoSendEdoLogDO();
            blnoSendEdoLogDo.setBlnoId(blnoBasInfoVo.getId());
            blnoSendEdoLogDo.setBlno(blnoBasInfoVo.getBlNo());
            blnoSendEdoLogDo.setEdoBatchNo(edoBaseVos.get(0).getEdoBatchNo());
            blnoSendEdoLogDo.setOperationType(doOpType.toUpperCase());
            blnoSendEdoLogDo.setSendPortCode(sendEdoPort.toUpperCase());
            blnoSendEdoLogDo.setSendJson(JSONObject.toJSONString(cntaoEdoRequestDto));
            if (!ObjectUtils.isEmpty(edoBaseResult)){
                blnoSendEdoLogDo.setSendStatus(edoBaseResult.getCode());
                blnoSendEdoLogDo.setResultJson(JSONObject.toJSONString(edoBaseResult));
            }
            blnoSendEdoLogService.writeSendEdoLog(blnoSendEdoLogDo);
        }
    }
    private void cnTxgSendLog(@NotNull List<EdoBaseVO> edoBaseVos, @NotNull CntxgEdoRequestDTO cntxgEdoRequestDto ,EdoBaseResult edoBaseResult,String sendEdoPort, String doOpType){
        if (!ObjectUtils.isEmpty(edoBaseVos.get(0)) && !ObjectUtils.isEmpty(edoBaseVos.get(0).getBlnoInfoVo().getBlnoBasInfoVO())){
            BlnoBaseInfoVO blnoBasInfoVo = edoBaseVos.get(0).getBlnoInfoVo().getBlnoBasInfoVO();
            BlnoSendEdoLogDO blnoSendEdoLogDo = new BlnoSendEdoLogDO();
            blnoSendEdoLogDo.setBlnoId(blnoBasInfoVo.getId());
            blnoSendEdoLogDo.setBlno(blnoBasInfoVo.getBlNo());
            blnoSendEdoLogDo.setEdoBatchNo(edoBaseVos.get(0).getEdoBatchNo());
            blnoSendEdoLogDo.setOperationType(doOpType.toUpperCase());
            blnoSendEdoLogDo.setSendPortCode(sendEdoPort.toUpperCase());
            blnoSendEdoLogDo.setSendJson(JSONObject.toJSONString(cntxgEdoRequestDto));
            if (!ObjectUtils.isEmpty(edoBaseResult)){
                blnoSendEdoLogDo.setSendStatus(edoBaseResult.getCode());
                blnoSendEdoLogDo.setResultJson(JSONObject.toJSONString(edoBaseResult));
            }
            blnoSendEdoLogService.writeSendEdoLog(blnoSendEdoLogDo);
        }

    }
    private void cnDlcSendLog(@NotNull List<EdoBaseVO> edoBaseVos, @NotNull CndlcEdoRequestDTO cndlcEdoRequestDto,EdoBaseResult edoBaseResult ,String sendEdoPort, String doOpType){
        if (!ObjectUtils.isEmpty(edoBaseVos.get(0)) && !ObjectUtils.isEmpty(edoBaseVos.get(0).getBlnoInfoVo().getBlnoBasInfoVO())){
            BlnoBaseInfoVO blnoBasInfoVo = edoBaseVos.get(0).getBlnoInfoVo().getBlnoBasInfoVO();
            BlnoSendEdoLogDO blnoSendEdoLogDo = new BlnoSendEdoLogDO();
            blnoSendEdoLogDo.setBlnoId(blnoBasInfoVo.getId());
            blnoSendEdoLogDo.setBlno(blnoBasInfoVo.getBlNo());
            blnoSendEdoLogDo.setEdoBatchNo(edoBaseVos.get(0).getEdoBatchNo());
            blnoSendEdoLogDo.setOperationType(doOpType.toUpperCase());
            blnoSendEdoLogDo.setSendPortCode(sendEdoPort.toUpperCase());
            blnoSendEdoLogDo.setSendJson(JSONObject.toJSONString(cndlcEdoRequestDto));
            if (!ObjectUtils.isEmpty(edoBaseResult)){
                blnoSendEdoLogDo.setSendStatus(edoBaseResult.getCode());
                blnoSendEdoLogDo.setResultJson(JSONObject.toJSONString(edoBaseResult));
            }
            blnoSendEdoLogService.writeSendEdoLog(blnoSendEdoLogDo);
        }

    }
}
